#define DEF_CACHE_SIZ 512
#define DEF_CACHE_MAXBYTES (512*32)
#define DEF_CACHE_PAGESIZ 512
#define DEF_CACHE_PSHIFT 9
#define DEF_CACHE_BUCKETS 3
#define DEF_CACHE_SWAPRATIO 4

struct cache{
    uint32 npg;
	uint32 maxpgs;
	uint32 pgsiz;
	int nbucket;
	int fd;
	int swapratio;
	pthread_rwlock_t lock;
	struct cnode **buckets;
	struct cnode *first,*last;
	struct cnode *ffirst,*flast;
	int swapnum;
	uchar flag;
#define CC_IN_TRANSACTION 1
	//double swaptime;
	//int swaptimes;
	//uint64 lastoffset;
	//double readtime;
	//int cmpnum;
	//int writenum;
};
#define TRANSACTION_SET(cc) (cc)->flag|=CC_IN_TRANSACTION
#define TRANSACTION_UNSET(cc) (cc)->flag&=~CC_IN_TRANSACTION
#define TRANSACTION_IN(cc) ((cc)->flag&CC_IN_TRANSACTION)
struct cnode{
    uint64 pgno;
#define CN_HMASK 0x0000ffff
#define CN_FMASK 0xffff0000
	uint32 haf;//hash and flag:high 16 bits->hash;low 16 bits->flag
	struct cnode *pre,*next;
	struct cnode *left,*right;
#define F_DIRTY  0x010000
#define F_FREE   0x020000
#define F_READ   0x040000
#define F_WRITE  0x080000
#define F_DELETE 0x100000
#define F_NEW    0x200000//in transaction
#define F_ERASE  0x400000
};
#define NDINUSE(nd) (((nd)->haf&F_READ)||((nd)->haf&F_WRITE))
struct cache* cachenew(int fd,int nbucket,int pagesiz,int maxbytes,int swapratio);
char* addpage(struct cache *cc,uint64 pgno,char *pg,uint32 flag);
char *getpage(struct cache *cc,uint64 pgno,uint32 flag);
int putpage(struct cache *cc,char *page,uint32 flag);
int delpage(struct cache *cc,char *p);
int addnode(struct cache *cc,uint32 hv1,uint16 hv2,uint64 pgno,struct cnode *nd,uint32 flag);
int cachedel(struct cache *cc);
int swapnode(struct cache* cc);
int check(struct cache *cc);
void* removenode(struct cache *cc,char *p);
int insertnode(struct cache *cc,void *in,uint32 flag);
int cachesyn(struct cache *cc);
int cremove(struct cache *cc,struct cnode *nd,uint32 hv1);
int cacheabort(struct cache *cc);
